; void monocromatizar_uno_asm (
; 	unsigned char *src,
; 	unsigned char *dst,
; 	int h,
; 	int w,
; 	int src_row_size,
; 	int dst_row_size
; );

global monocromatizar_uno_asm

section .text

monocromatizar_uno_asm:
	;; TODO: Implementar
	push rbp
	mov rbp, rsp
	push rbx
	push r12
	push r13
	push r14
	push r15

	pxor xmm7, xmm7

	mov r15, rcx
	shr r15, 2					;divido por la cantidad de pixels simultaneos que proceso

	mov r13, rcx
	and r13, 3					;calculo el resto

	xor r12, r12
	cicloFilas:
		xor r11, r11
		cicloColumnas:
			lea r10, [rdi + r11*8]
			lea r10, [r10 + r11*4]
			movdqu xmm0, [r10]		;xmm0 = xx|xx|xx|xx|b4|g4|r4|b3|g3|r3|b2|g2|r2|b1|g1|r1
			movdqu xmm3, xmm0
			pslldq xmm3, 2			;xmm3 = xx|xx|b4|g4|r4|b3|g3|r3|b2|g2|r2|b1|g1|r1|00|00

			punpcklbw xmm0, xmm7		;xmm0 = 00|00|00|00|00|b2|00|g2|00|r2|00|b1|00|g1|00|r1

			movdqu xmm1, xmm0		;xmm1 = 00|00|00|00|00|b2|00|g2|00|r2|00|b1|00|g1|00|r1
			movdqu xmm2, xmm0		;xmm2 = 00|00|00|00|00|b2|00|g2|00|r2|00|b1|00|g1|00|r1

			psrldq xmm1, 2			;xmm1 = 00|00|00|00|00|00|00|b2|00|g2|00|r2|00|b1|00|g1
			psrldq xmm2, 4			;xmm2 = 00|00|00|00|00|00|00|00|00|b2|00|g2|00|r2|00|b1

			paddw xmm0, xmm1
			paddw xmm0, xmm1
			paddw xmm0, xmm2
			psrlw xmm0, 2			;S1 = (r1+2*g1+b1)/4	|	S2 = (r2+2*g2+b2)/4
							;xmm0 = 00|00|00|00|00|xx|00|xx|00|S2|00|xx|00|xx|00|S1
;
			punpckhbw xmm3, xmm7		;xmm3 = 00|00|00|00|00|b4|00|g4|00|r4|00|b3|00|g3|00|r3

			movdqu xmm4, xmm3		;xmm4 = 00|00|00|00|00|b4|00|g4|00|r4|00|b3|00|g3|00|r3
			movdqu xmm5, xmm3		;xmm5 = 00|00|00|00|00|b4|00|g4|00|r4|00|b3|00|g3|00|r3

			psrldq xmm4, 2			;xmm4 = 00|00|00|00|00|00|00|b4|00|g4|00|r4|00|b3|00|g3
			psrldq xmm5, 4			;xmm5 = 00|00|00|00|00|00|00|00|00|b4|00|g4|00|r4|00|b3

			paddw xmm3, xmm4
			paddw xmm3, xmm4
			paddw xmm3, xmm5
			psrlw xmm3, 2			;S3 = (r3+2*g3+b3)/4	|	S4 = (r4+2*g4+b4)/4
							;xmm3 = 00|00|00|00|00|xx|00|xx|00|S4|00|xx|00|xx|00|S3


			packuswb xmm0, xmm7		;xmm0 = 00|00|xx|xx|S2|xx|xx|S1
			packuswb xmm3, xmm7		;xmm0 = 00|00|xx|xx|S4|xx|xx|S3

			pextrw eax, xmm3, 0		;eax = 00|00|xx|S3
			pextrw ebx, xmm3, 1		;ebx = 00|00|S4|xx
			mov ah, bh			;eax = 00|00|S4|S3
			shl eax, 16			;eax = S4|S3|00|00
			pextrw ebx, xmm0, 0		;ebx = 00|00|xx|S1
			mov al, bl			;eax = S4|S3|00|S1
			pextrw ebx, xmm0, 1		;ebx = 00|00|S2|xx
			mov ah, bh			;eax = S4|S3|S2|S1
			mov [rsi + 4 * r11], eax
		inc r11
		cmp r11, r15
		jb cicloColumnas

		cmp r13, 0
		je se_proceso_linea_completa
		shl r11, 1
		procesar_lo_que_queda:
			lea r10, [rdi + r11*2]
			lea r10, [r10 + r11]
			movd xmm0, [r10]		;xmm0 = xx|b1|g1|r1

			punpcklbw xmm0, xmm7		;xmm0 = 00|xx|00|b1|00|g1|00|r1

			movq xmm1, xmm0			;xmm1 = 00|xx|00|b1|00|g1|00|r1
			movq xmm2, xmm0			;xmm2 = 00|xx|00|b1|00|g1|00|r1

			psrldq xmm1, 2			;xmm1 = 00|00|00|r2|00|b1|00|g1
			psrldq xmm2, 4			;xmm2 = 00|xx|00|xx|00|r2|00|b1

			paddw xmm0, xmm1
			paddw xmm0, xmm1
			paddw xmm0, xmm2
			psrlw xmm0, 2			;S1 = (r1+2*g1+b1)/4
							;xmm0 = 00|xx|00|xx|00|xx|00|S1

			packuswb xmm0, xmm7		;xmm0 = 00|00|xx|xx|00|xx|xx|S1
			pextrw eax, xmm0, 0		;eax = 00|00|xx|S1

			mov [rsi + r11], al
		inc r11
		cmp r11, rcx
		jb procesar_lo_que_queda
		se_proceso_linea_completa:

		lea rdi, [rdi + r8]
		lea rsi, [rsi + r9]
	inc r12
	cmp r12, rdx
	jb cicloFilas

	pop r15
	pop r14
	pop r13
	pop r12
	pop rbx
	pop rbp
	ret
